Skip to content

Conversation

@ase-101
Copy link
Contributor

@ase-101 ase-101 commented Jan 25, 2026

Summary by CodeRabbit

  • New Features

    • Added error codes to surface PKCE requirements and an additional configuration error.
  • Bug Fixes

    • Clearer PKCE enforcement with updated error responses.
    • Relaxed JWK validation to allow deferred checks (may affect key handling).
  • Refactor

    • Centralized feature-flag initialization and simplified authorization flows.
    • Removed server-profile caching.
  • Tests

    • Added/updated tests for feature flags, PKCE, and PAR behaviors.

✏️ Tip: You can customize this high-level summary in your review settings.

Signed-off-by: ase-101 <[email protected]>
Signed-off-by: ase-101 <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Jan 25, 2026

Walkthrough

Centralizes server-profile feature flags into a ServerProfile bean, replaces additionalConfig map with explicit boolean flags in OIDCTransaction, adds USE_PKCE and invalid_additional_config error codes, enforces per-transaction PKCE, adjusts JWK validation, and updates tests and OpenAPI enums accordingly.

Changes

Cohort / File(s) Summary
OpenAPI Specification
docs/esignet-openapi.yaml
Adds use_pkce to multiple errorCode enums (POST /client-mgmt/oidc-client, /authorize oauth-details v1/v2/v3) and adds invalid_additional_config to POST /client-mgmt/oauth-client.
Error Constants & Core DTOs
esignet-core/src/main/java/io/mosip/esignet/core/constants/ErrorConstants.java, esignet-core/src/main/java/io/mosip/esignet/core/dto/OIDCTransaction.java, esignet-core/src/main/java/io/mosip/esignet/core/dto/ServerProfile.java
Adds USE_PKCE constant; removes additionalConfigMap and introduces booleans requirePushedAuthorizationRequests, dpopBoundAccessToken, requirePKCE in OIDCTransaction; adds new ServerProfile DTO.
Configuration & Bootstrapping
esignet-service/src/main/java/io/mosip/esignet/config/AppConfig.java, esignet-service/src/main/resources/application-default.properties
Adds serverProfile() bean to load profile features from repository and exposes ServerProfile; removes serverprofile cache configuration from defaults.
Repository & Caching
oidc-service-impl/src/main/java/io/mosip/esignet/repository/ServerProfileRepository.java
Removes @Cacheable annotation from findByProfileName(...) (cache behavior removed).
Service Layer Refactoring
oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationHelperService.java, oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationServiceImpl.java
Removes getFeaturesByProfileName(); introduces setFeatureFlags(OIDCTransaction, ClientDetail) to populate flags from ServerProfile or client config; updates method signatures to drop explicit feature-map params; enforces PKCE per-transaction and throws USE_PKCE when required and missing.
Tests
esignet-service/src/test/java/io/mosip/esignet/AppConfigTest.java, oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationHelperServiceTest.java, oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationServiceTest.java
Adds AppConfig tests for serverProfile bean; removes feature-retrieval tests; extends AuthorizationServiceTest with PKCE/PAR/feature-flag scenarios and updates expectations to USE_PKCE.
Utilities & JWK handling
esignet-core/src/main/java/io/mosip/esignet/core/util/IdentityProviderUtil.java, esignet-core/src/test/java/io/mosip/esignet/core/IdentityProviderUtilTest.java
Relaxed alg/use null handling: only kty required non-null; alg/use allowed null but blank values rejected when present; tests adjusted accordingly.
Postman collection
postman-collection/eSignet.postman_collection.json
Adds publicKey_jwk.alg = "RS256" and publicKey_jwk.use = "sig" when creating RSA JWK.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant Client
participant AuthService as AuthorizationServiceImpl
participant ServerProfileBean as ServerProfile
participant Repo as ServerProfileRepository
participant DB as Database
participant Transaction as OIDCTransaction

Client->>AuthService: /authorize (oauth details) request
AuthService->>ServerProfileBean: resolve profile name (injected)
ServerProfileBean->>Repo: findByProfileName(profileName)
Repo->>DB: query server_profile rows
DB-->>Repo: rows
Repo-->>ServerProfileBean: ServerProfile list
ServerProfileBean-->>AuthService: populated ServerProfile (feature map)
AuthService->>Transaction: setFeatureFlags(oidcTransaction, clientDetail)
AuthService->>AuthService: validate (if requirePKCE && missing code_challenge)
alt PKCE required and missing
AuthService-->>Client: error response (errorCode: use_pkce)
else PKCE not required or provided
AuthService-->>Client: proceed with oauth details / success
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • Md-Humair-KK
  • pvsaidurga

Poem

🐰 I nibble configs, flags take flight,
PKCE hops in to guard the night,
Profiles planted in a bean so neat,
Enums updated—errors we greet,
Hopping on, the flow feels right! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The pull request title "ES-2712" is an issue ID only, providing no meaningful information about the actual code changes being introduced. Replace the title with a clear, descriptive summary of the main change, such as 'Refactor server profile feature flags and PKCE handling' or 'Replace additional config map with explicit feature flags in OIDC transaction'.
Docstring Coverage ⚠️ Warning Docstring coverage is 9.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@esignet-core/src/main/java/io/mosip/esignet/core/dto/OIDCTransaction.java`:
- Around line 75-90: Update the database seed in the esignet-server profile SQL
so that the fapi2.0 profile no longer sets require_pkce=true: remove or set
require_pkce to false for the fapi2.0 INSERT/UPDATE and keep only PAR
(require_pushed_authorization_requests), DPOP (dpop_bound_access_token), and JWE
settings; then add a new nisdsp profile row in the same seed script with
features require_pushed_authorization_requests=true,
dpop_bound_access_token=true, require_pkce=true and set the proper
userinfo_response_type value (and any related DPoP nonce TTL/JKT columns if
present) so that nisdsp contains PAR, DPoP, PKCE and the userinfo_response_type
as specified.

In `@esignet-service/src/main/java/io/mosip/esignet/config/AppConfig.java`:
- Around line 85-105: Handle a null serverProfile explicitly and replace the
hard-coded error string with a constant: in the serverProfile() method check if
(serverProfile == null || "none".equalsIgnoreCase(serverProfile)) then return
the empty profile to avoid passing null into
serverProfileRepository.findByProfileName; when throwing the exception use
ErrorConstants.INVALID_SERVER_PROFILE instead of the literal
"INVALID_SERVER_PROFILE"; and add a public static final String
INVALID_SERVER_PROFILE = "invalid_server_profile" to the ErrorConstants class so
the constant is defined.

In
`@oidc-service-impl/src/main/java/io/mosip/esignet/services/AuthorizationServiceImpl.java`:
- Around line 630-635: The Javadoc for the method in AuthorizationServiceImpl
describing defaults is inaccurate: the code actually defaults feature booleans
to false and response type to "JWS" rather than "all available features". Update
the Javadoc to state the actual default behavior (booleans default to false and
response type defaults to "JWS"), or if the intended behavior is to enable all
features by default, change the implementation in the method that sets
additional config on the OIDCTransaction to initialize those booleans to true
and response type accordingly; reference the AuthorizationServiceImpl method
that takes OIDCTransaction and adjusts server/client additional config and the
OIDCTransaction fields that store the booleans and response type to make the
change.

In
`@oidc-service-impl/src/test/java/io/mosip/esignet/services/AuthorizationServiceTest.java`:
- Around line 115-117: Tests are failing because the `@Mock` ServerProfile returns
null for getFeatureMap(), causing an NPE when setFeatureFlags is exercised; in
the AuthorizationServiceTest setUp() method stub ServerProfile#getFeatureMap()
to return an empty Map (e.g., Collections.emptyMap()) so tests have a safe
default; update the setup in AuthorizationServiceTest (the setUp() method) to
add a when(serverProfile.getFeatureMap()).thenReturn(emptyMap) stub before
invoking code that calls setFeatureFlags.
🧹 Nitpick comments (3)
esignet-core/src/main/java/io/mosip/esignet/core/dto/ServerProfile.java (1)

12-17: Consider initializing featureMap to prevent potential NPE.

While the current usage in AppConfig.serverProfile() always sets the map, initializing the field defensively would prevent accidental NPE if the DTO is used elsewhere without explicit initialization.

♻️ Optional defensive initialization
 `@Data`
 public class ServerProfile {
 
     private String name;
-    private Map<String, String> featureMap;
+    private Map<String, String> featureMap = new HashMap<>();
 }
esignet-service/src/test/java/io/mosip/esignet/AppConfigTest.java (2)

34-35: Remove unused @Value annotation.

The @Value annotation has no effect in a @ExtendWith(MockitoExtension.class) test since Spring's property injection is not active. The field is never used as all tests set the value via ReflectionTestUtils.

♻️ Remove dead code
-    `@Value`("${mosip.esignet.server.profile:none}")
-    private String serverProfile;
-
     `@Test`
     void serverProfile_ServerProfileIsNone_returnsWithNoFeatures() throws EsignetException {

57-63: Test relies on implicit repository behavior for null input.

The test serverProfile_NullProfile_ThrowsException passes because findByProfileName(null) returns null or empty list. However, this test doesn't mock the repository behavior, making the assertion dependent on default mock behavior (returning null). Consider explicitly mocking for clarity.

♻️ Add explicit mock for clarity
 `@Test`
 void serverProfile_NullProfile_ThrowsException() {
     ReflectionTestUtils.setField(appConfig, "serverProfile", null);
+    when(serverProfileRepository.findByProfileName(null)).thenReturn(null);

     EsignetException exception = assertThrows(EsignetException.class, () -> appConfig.serverProfile());
     assertEquals("INVALID_SERVER_PROFILE", exception.getMessage());
 }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
esignet-core/src/main/java/io/mosip/esignet/core/util/IdentityProviderUtil.java (1)

226-242: NullPointerException when alg or use is missing from JWK.

The condition at line 226 now only checks keyType == null, but line 240 calls alg.isEmpty() and use.isEmpty(). If a JWK is provided without these fields, this will throw an NPE instead of the expected EsignetException.

🐛 Proposed fix to guard against null values
-        if (keyType == null) {
+        if (keyType == null || alg == null || use == null) {
             throw new EsignetException(ErrorConstants.INVALID_PUBLIC_KEY);
         }

Alternatively, if null alg/use should be allowed to pass the initial check but still validated later:

-            if (alg.isEmpty() || use.isEmpty()) {
+            if (alg == null || alg.isEmpty() || use == null || use.isEmpty()) {
                 throw new EsignetException(ErrorConstants.INVALID_PUBLIC_KEY);
             }

Copy link
Contributor

@zesu22 zesu22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks Good

Signed-off-by: ase-101 <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@esignet-core/src/main/java/io/mosip/esignet/core/util/IdentityProviderUtil.java`:
- Around line 226-239: The validation in IdentityProviderUtil that checks alg
and use currently only rejects blank values but allows nulls, contradicting
tests; update the validation (in the method that builds the JWK string where
keyType is switched to RsaJsonWebKey/EllipticCurveJsonWebKey) to throw
EsignetException(ErrorConstants.INVALID_PUBLIC_KEY) if alg is null or blank OR
if use is null or blank (i.e., replace the current (alg != null &&
alg.isBlank()) || (use != null && use.isBlank()) check with a null-or-blank
check for both alg and use so missing/null values fail).
🧹 Nitpick comments (3)
esignet-core/src/test/java/io/mosip/esignet/core/IdentityProviderUtilTest.java (3)

231-241: Test name no longer reflects what is being tested.

The test getJWKString_withInvalidAlgForRSA_thenFail now tests an empty string for alg, not an invalid algorithm for RSA keys. Consider renaming to getJWKString_withEmptyAlg_thenFail for clarity.

Suggested rename
-    public void getJWKString_withInvalidAlgForRSA_thenFail() {
+    public void getJWKString_withEmptyAlg_thenFail() {

243-254: Test name no longer reflects what is being tested.

The test getJWKString_withInvalidUse_thenFail now tests a blank string for use, not an invalid use value. Consider renaming to getJWKString_withBlankUse_thenFail for clarity.

Suggested rename
-    public void getJWKString_withInvalidUse_thenFail() {
+    public void getJWKString_withBlankUse_thenFail() {

174-192: Missing test coverage for the new behavior allowing null alg/use.

The existing tests getJWKString_withMissingAlg_thenFail and getJWKString_withMissingUse_thenFail pass due to missing RSA key components (n, e), not because of missing alg/use. With the implementation change now allowing null alg and use, consider adding positive test cases that verify a complete RSA JWK without alg or use succeeds.

Suggested additional test
`@Test`
public void getJWKString_withValidRSAKeyWithoutAlgAndUse_thenPass() {
    Map<String, Object> jwkMap = new HashMap<>();
    jwkMap.put("kty", "RSA");
    jwkMap.put("n", "oahUIzUup5kqncCkHk5Zb1pRrLx7e6YtM-9jX1f5e6mHnZFkC2LJUZ0sEh0n5Y5KnQfW9s7d7gK2b8P0EEl0h3ZyHkWzA3YbsgzB4pDxP4RxMZ1I8xD2z3UvfA1zjvKDHz6wEweq4hVJ8nS8GzZJ2E_vb3s");
    jwkMap.put("e", "AQAB");
    // No alg or use - should now pass
    String jwkJson = IdentityProviderUtil.getJWKString(jwkMap);
    Assertions.assertTrue(jwkJson.contains("\"kty\":\"RSA\""));
}

@zesu22 zesu22 merged commit 14d70d9 into mosip:develop Jan 27, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants